package com.ucode.springboot.starter.ESsearch.repository;

import java.util.List;
import java.util.Map;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Response;
import org.elasticsearch.index.query.QueryBuilder;

import com.ucode.springboot.starter.ESsearch.enums.SqlFormat;
import com.ucode.springboot.starter.ESsearch.repository.query.Advanc;
import com.ucode.springboot.starter.ESsearch.repository.query.PageSortHighLight;
import com.ucode.springboot.starter.ESsearch.repository.query.PhraseSuggestParam;
import com.ucode.springboot.starter.ESsearch.repository.response.ScrollResponse;
import com.ucode.tool.base.Paginator;

/**
 * ES 索引基础操作
 * @author: liliang
 * @date: 2019年12月30日 下午5:12:02
 */
public interface ElasticsearchSearchTemplate<T, ID> {

    /**
     * 根据ID查询
     * @param id 索引数据id值
     * @param clazz 索引pojo类类型
     * @return
     * @throws Exception
     */
    public T getById(ID id, Class<T> clazz) throws Exception;

    /**
     * 根据ID列表批量查询
     * @param ids 索引数据id值数组
     * @param clazz 索引pojo类类型
     * @return
     * @throws Exception
     */
    public List<T> getByIds(ID[] ids, Class<T> clazz) throws Exception;

    /**
     * id数据是否存在
     * @param id 索引数据id值
     * @param clazz 索引pojo类类型
     * @return
     */
    public boolean exists(ID id,Class<T> clazz) throws Exception;
    
    
    /**
     * 原生查询
     * @param searchRequest 原生查询请求对象
     * @return
     * @throws Exception
     */
    public SearchResponse search(SearchRequest searchRequest) throws Exception;
    
    
    /**
     * 条件查询,默认返回200条
     * @param queryBuilder 查询条件
     * @param clazz 索引pojo类类型
     * @return
     * @throws Exception
     */
    public List<T> search(QueryBuilder queryBuilder, Class<T> clazz) throws Exception;
    
    /**
     * 跨索引条件查询
     * @param queryBuilder 查询条件
     * @param clazz 索引pojo类类型
     * @param indexs 索引名称
     * @return
     * @throws Exception
     */
    public List<T> search(QueryBuilder queryBuilder, Class<T> clazz,String... indexs) throws Exception;
    
    /**
     * 条件查询，指定最大返回条数
     * @param queryBuilder 查询条件
     * @param limitSize 最大返回条数
     * @param clazz 索引pojo类类型
     * @return
     * @throws Exception
     */
    public List<T> search(QueryBuilder queryBuilder,int limitSize, Class<T> clazz) throws Exception;
    
    /**
     * 跨索引条件查询，指定最大返回条数
     * @param queryBuilder 查询条件
     * @param limitSize 最大返回条数
     * @param clazz 索引pojo类类型
     * @param indexs 索引名称
     * @return
     * @throws Exception
     */
    public List<T> search(QueryBuilder queryBuilder,int limitSize, Class<T> clazz,String... indexs) throws Exception;
    
    /**
     * uri条件查询
     * @param uri uri查询的查询条件
     * @param clazz 索引pojo类类型
     * @return
     * @throws Exception
     */
    public List<T> searchUri(String uri,Class<T> clazz)throws Exception;

    /**
     * 通过sql进行查询
     * @param sql sql脚本（支持mysql语法）
     * @param sqlFormat sql请求返回类型
     * @return
     * @throws Exception
     */
    public String queryBySQL(String sql, SqlFormat sqlFormat) throws Exception;
    
    /**
     * 查询数量
     * @param queryBuilder 查询条件
     * @param clazz 索引pojo类类型
     * @return
     * @throws Exception
     */
    public long count(QueryBuilder queryBuilder, Class<T> clazz) throws Exception;
    
    /**
     * 跨索引查询数量
     * @param queryBuilder 查询条件
     * @param clazz 索引pojo类类型
     * @param indexs 索引名称
     * @return
     * @throws Exception
     */
    public long count(QueryBuilder queryBuilder, Class<T> clazz,String... indexs) throws Exception;
    
    /**
     * 支持分页、高亮、排序的查询
     * @param queryBuilder 查询条件
     * @param pageSortHighLight 分页+排序+高亮对象封装
     * @param clazz 索引pojo类类型
     * @return
     * @throws Exception
     */
    public Paginator<T> search(QueryBuilder queryBuilder, PageSortHighLight pageSortHighLight, Class<T> clazz) throws Exception;
    
    /**
     * 支持跨索引、分页、高亮、排序的查询
     * @param queryBuilder 查询条件
     * @param pageSortHighLight 分页+排序+高亮对象封装
     * @param clazz 索引pojo类类型
     * @param indexs 索引名称
     * @return
     * @throws Exception
     */
    public Paginator<T> search(QueryBuilder queryBuilder, PageSortHighLight pageSortHighLight, Class<T> clazz,String... indexs) throws Exception;
    
    /**
     * 支持分页、高亮、排序、指定返回字段、路由的查询
     * @param queryBuilder 查询条件
     * @param advanc （可支持分页、高亮、排序、指定返回字段、路由、searchAfter信息的定制）
     * @param clazz 索引pojo类类型
     * @return
     * @throws Exception
     */
    public Paginator<T> search(QueryBuilder queryBuilder, Advanc advanc, Class<T> clazz) throws Exception;
    
    /**
     * 支持分页、高亮、排序、指定返回字段、路由的查询（跨索引）
     * @param queryBuilder 查询条件
     * @param advanc 查询增强对象（可支持分页、高亮、排序、指定返回字段、路由、searchAfter信息的定制）
     * @param clazz 索引pojo类类型
     * @param indexs 索引名称
     * @return
     * @throws Exception
     */
    public Paginator<T> search(QueryBuilder queryBuilder, Advanc advanc, Class<T> clazz,String... indexs) throws Exception;
    
    /**
     * 搜索建议,自动补齐
     * @author liliang
     * @date 2020年1月9日
     * @param fieldName 搜索建议对应查询字段
     * @param fieldValue 搜索建议查询条件
     * @param clazz 索引文档类类型
     * @return
     * @throws Exception
     */
    public List<String> searchSuggest(String fieldName,String fieldValue,Class<T> clazz) throws Exception;

    /**
     * 跨索引，搜索建议,自动补齐
     * @author liliang
     * @date 2020年1月9日
     * @param fieldName 搜索建议对应查询字段
     * @param fieldValue 搜索建议查询条件
     * @param clazz 索引文档类类型
     * @param indexs 索引名称
     * @return
     * @throws Exception
     */
    public List<String> searchSuggest(String fieldName,String fieldValue,Class<T> clazz,String... indexs) throws Exception;

    /**
     * 基于短语错别纠正的搜索建议
     * @author liliang
     * @date 2020年1月9日
     * @param fieldName 搜索建议对应查询字段
     * @param fieldValue 搜索建议查询条件
     * @param param 定制短语错别纠正参数
     * @param clazz 索引文档类类型
     * @return
     * @throws Exception
     */
    public List<String> searchPhraseSuggest(String fieldName, String fieldValue, PhraseSuggestParam param, Class<T> clazz) throws Exception;

    /**
     * 基于短语错别纠正的跨索引搜索建议
     * @author liliang
     * @date 2020年1月9日
     * @param fieldName 搜索建议对应查询字段
     * @param fieldValue 搜索建议查询条件
     * @param param 定制短语错别纠正参数
     * @param clazz 索引文档类类型
     * @param indexs 索引名称集合
     * @return
     * @throws Exception
     */
    public List<String> searchPhraseSuggest(String fieldName,String fieldValue,PhraseSuggestParam param,Class<T> clazz,String... indexs) throws Exception;

    /**
     * 创建scroll
     * @author liliang
     * @date 2020年1月9日
     * @param queryBuilder 查询条件
     * @param clazz 索引文档类类型
     * @param time scroll窗口时间，单位：小时
     * @param size scroll查询每次查询条数
     * @return
     * @throws Exception
     */
    public ScrollResponse<T> createScroll(QueryBuilder queryBuilder, Class<T> clazz, long time, int size) throws Exception;

    /**
     * 创建scroll
     * @author liliang
     * @date 2020年1月9日
     * @param queryBuilder 查询条件
     * @param clazz 索引文档类类型
     * @param time scroll窗口时间，单位：小时
     * @param size scroll查询每次查询条数
     * @param indexs 索引名称
     * @return
     * @throws Exception
     */
    public ScrollResponse<T> createScroll(QueryBuilder queryBuilder, Class<T> clazz, long time, int size , String... indexs) throws Exception;


    /**
     * scroll方式查询
     * @author liliang
     * @date 2020年1月9日
     * @param clazz 索引文档类类型
     * @param time scroll窗口时间，单位：小时
     * @param scrollId scroll查询id，from ScrollResponse
     * @return
     * @throws Exception
     */
    public ScrollResponse<T> queryScroll(Class<T> clazz, long time , String scrollId) throws Exception;
    
    /**
     * 保存Template
     * @author liliang
     * @date 2020年1月9日
     * @param templateName 模版名称
     * @param templateSource 模版内容
     * @return
     */
    public Response saveTemplate(String templateName,String templateSource) throws Exception;
    
    /**
     * Template方式搜索，Template已经保存在script目录下
     * @author liliang
     * @date 2020年1月9日
     * @param templateParams 模版参数
     * @param templateName 模版名称
     * @param clazz 索引文档类类型
     * @return
     */
    public List<T> searchTemplate(Map<String, Object> templateParams,String templateName,Class<T> clazz) throws Exception;

    /**
     * Template方式搜索，Template内容以参数方式传入
     * @author liliang
     * @date 2020年1月9日
     * @param templateParams 模版参数
     * @param templateSource 模版内容
     * @param clazz 索引文档类类型
     * @return
     */
    public List<T> searchTemplateBySource(Map<String, Object> templateParams,String templateSource,Class<T> clazz) throws Exception;

}
